package com.xiaomaoguai.crs.web.utils;

import com.alibaba.fastjson.JSON;
import com.billionsfinance.crs.model.system.MessageModel;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 错误异常处理
 *
 * @author Fukun
 *         date 2016年4月22日
 */
public class CrsExceptionHandler implements HandlerExceptionResolver {

	private static final Logger LOGGER = LoggerFactory.getLogger(CrsExceptionHandler.class);

	/**
	 * 默认view错误挑战处理
	 *
	 * @param request  req
	 * @param response resp
	 * @param handler  handler
	 * @param ex       exception
	 * @return ModelAndView
	 */
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		String requestURL = request.getRequestURL().toString();
		LOGGER.error("请求连接[{}]时,发生了一个异常. ", requestURL, ex);

		ModelAndView mv = new ModelAndView();

		//控制器请求造成的异常,并且是ajax请求的
		if (handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			//spring ajax 返回含有 ResponseBody 或者 RestController注解
			ResponseBody annotation = handlerMethod.getMethodAnnotation(ResponseBody.class);
			RestController restAnnotation = handlerMethod.getBean().getClass().getAnnotation(RestController.class);
			// ajax 异常
			if (null != annotation || null != restAnnotation) {
				response.setContentType("application/json;charset=UTF-8");
				mv.addObject("result", JSON.toJSON(new MessageModel(false, ExceptionUtils.getStackTrace(ex))));
				mv.setViewName("/common/result");
			} else {
				mv.addObject("exception", ex);
				mv.setViewName("/common/exception");
			}
		}
		return mv;
	}

}